﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace PBGenerator
{
    internal class Program
    {
        public static string getAppPath()
        {
            return AppDomain.CurrentDomain.BaseDirectory;
        }

        private static string getProtocPath()
        {
            return Program.getAppPath() + "\\protoc\\protoc";
        }

        private static string getProtoGenPath()
        {
            return Program.getAppPath() + "\\protogen\\protogen";
        }

        private static string getPrecompilePath()
        {
            return Program.getAppPath() + "\\precompile\\precompile";
        }

        private static string getProtoFilePath()
        {
            return Program.getAppPath() + "ProtoFile";
        }

        private static string getProtocFilePath()
        {
            return Program.getAppPath() + "Protoc";
        }

        private static string getProtocFilePath(string fileName)
        {
            return Program.getProtocFilePath() + "\\" + fileName;
        }

        private static string getCommProtoFilePath(string fileName)
        {
            return Program.getProtoFilePath() + "\\" + fileName;
        }

        private static string getDotNet2Path()
        {
            string systemdir = Environment.GetFolderPath(Environment.SpecialFolder.System);
            string windir = Path.GetDirectoryName(systemdir);
            return windir + "\\Microsoft.NET\\Framework\\v2.0.50727";
        }

        private static void waitKeyForExit()
        {
            Console.WriteLine("按任意键退出！！！");
            Console.ReadKey();
            Environment.Exit(0);
        }

        public static void writeInfo(string info)
        {
            Console.WriteLine(info);
        }

        private static void Main(string[] args)
        {

            
            if (args.Length <= 1)
            {
                Console.WriteLine("请输入协议Proto文件名称（包含.proto)！！！ 同时末尾标注是否为 : ToILR");
            }
            else
            {
                bool GeneratorToILR = args[args.Length-1].Equals("ToILR");
                Console.WriteLine("\r\n");
                DirectoryInfo protoFileFolder = new DirectoryInfo(Program.getProtoFilePath());
                if (!protoFileFolder.Exists)
                {
                    protoFileFolder.Create();
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("模板文件不存在！！！");
                    Program.waitKeyForExit();
                }
                if (protoFileFolder.GetFiles().Length < 1)
                {
                    Console.WriteLine("模板文件不存在！！！");
                    Program.waitKeyForExit();
                }
                DirectoryInfo cscFile = new DirectoryInfo(Program.getDotNet2Path());
                if (!cscFile.Exists)
                {
                    Console.WriteLine("请安装.NetFramework2.0！！！");
                    Program.waitKeyForExit();
                }
                //Directory.CreateDirectory(string.Concat(new object[]
                //{
                //    AppDomain.CurrentDomain.BaseDirectory,
                //    Path.DirectorySeparatorChar,
                //    "generate",
                //    Path.DirectorySeparatorChar,
                //    "java"
                //}));
                //Directory.CreateDirectory(string.Concat(new object[]
                //{
                //    AppDomain.CurrentDomain.BaseDirectory,
                //    Path.DirectorySeparatorChar,
                //    "generate",
                //    Path.DirectorySeparatorChar,
                //    "csharp"
                //}));
                string commProtoFileName = args[0];

                List<FileInfo> commProFiles = new List<FileInfo>();
                int protoFileCount = 0;
                for (int i = 0; i < args.Length; i++)
                {
                    FileInfo commFile = new FileInfo(Program.getCommProtoFilePath(args[i]));
                    if (commFile.Exists)
                    {
                        protoFileCount++;
                        commProFiles.Add(commFile);
                    }
                }

                //FileInfo commProtoFile = new FileInfo(Program.getCommProtoFilePath(commProtoFileName));
                if (protoFileCount <= 0)
                {
                    Console.WriteLine("ProtoFile:" + "不存在！！！");
                    Program.waitKeyForExit();
                }

                #region ToILR 替换
                //string patternToILR = "[ToILR]\\s*[A-Za-z0-9\\u4e00-\\u9fa5]*\\s*";
                string noOpDefinePattern = "//#no_opdefine\\s*[A-Za-z0-9\\u4e00-\\u9fa5]*\\s*";
                string endMsgPattern = "}\\s*[A-Za-z0-9\\u4e00-\\u9fa5]*\\s*";

                string regionPattern = "//#region\\s*[A-Za-z0-9\\u4e00-\\u9fa5]*\\s*";
                string endregion = "//#endregion\\s*[A-Za-z0-9\\u4e00-\\u9fa5]*\\s*";
                #endregion

                Console.WriteLine("文件列表:");
                StringBuilder protoTick = new StringBuilder();
                bool toILRFlag = false;

                bool startRegionPattern = false;

                for (int i = 0; i < commProFiles.Count; i++)
                {
                    var commProFile = commProFiles[i];
                    string[] slines = File.ReadAllLines(commProFile.FullName, Encoding.UTF8);
                   
                    if (slines.Any(line => Regex.IsMatch(line, noOpDefinePattern)))
                    {
                        Console.WriteLine("[" + i + "]" + commProFile.Name + ": 文件包含no_opdefine标识，跳过该文件。");
                        continue;
                    }

                    Console.WriteLine("[" + i + "]" + commProFile.Name);
                    protoTick.Clear();
                    toILRFlag = false;
                    startRegionPattern = false;
                    if (GeneratorToILR)//转到ilr 需要吧非ilr标签的全部剔除
                    {
                        foreach (var line in slines)
                        {
                            if(Regex.IsMatch(line, regionPattern))
                            {
                                startRegionPattern = true;
                                protoTick.AppendLine(line);
                                continue;
                            }
                            if (Regex.IsMatch(line, endregion))
                            {
                                startRegionPattern = false;
                            }

                            if(startRegionPattern)//开始解析message了 
                            {
                                if (line.StartsWith("[ToILR]"))
                                {
                                    toILRFlag = true;
                                    continue;
                                }

                                if (toILRFlag)
                                {
                                    if(Regex.IsMatch(line, endMsgPattern))
                                    {
                                        toILRFlag = false;
                                        protoTick.AppendLine(line);
                                        continue;
                                    }
                                    protoTick.AppendLine(line);
                                    continue;
                                }
                            }
                            else//之外的全部加进去
                            {
                                protoTick.AppendLine(line);
                            }
                        }
                    }
                    else//转到Native ，只需要吧ilr标签的抛弃
                    {
                        foreach (var line in slines)
                        {
                            if (line.StartsWith("[ToILR]"))
                            {
                                toILRFlag = true;
                                continue;
                            }
                            if (toILRFlag && Regex.IsMatch(line, endMsgPattern))
                            {
                                toILRFlag = false;
                                continue;
                            }
                            else if(toILRFlag && !Regex.IsMatch(line, endMsgPattern))
                            {
                                continue;
                            }
                            
                            protoTick.AppendLine(line);
                        }
                    }

                    //重新写入
                    //if (!Directory.Exists(Program.getGenerated()))
                    //{
                    //    Directory.CreateDirectory(Program.getGenerated());
                    //}
                    //File.WriteAllText(Program.getGeneratedFilePath(commProFile.Name), protoTick.ToString(), new UTF8Encoding());

                    File.WriteAllText(commProFile.FullName, protoTick.ToString(), new UTF8Encoding());
                    File.Copy(commProFile.FullName, Program.getProtocFilePath(commProFile.Name),true);
                }
            }
        }
    }
}
